/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * Project Name: lmrp-android framework
 * Create Time: 16-2-16 下午6:48
 */

package com.lenovo.framework.base;

import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.jakewharton.rxbinding.widget.RxTextView;
import com.jakewharton.rxbinding.widget.TextViewTextChangeEvent;
import com.lenovo.framework.R;
import com.lenovo.framework.util.DLog;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;

/**
 * Since we cannot customize the android framework actionbar in so many ways, we
 * mock an actionbar to our needs with title, menu, tools button available here.
 * @author JeffreyHe
 * @version 1.0
 * @updated 25-一月-2016 15:39:39
 */
public abstract class BaseActionBarMockingActivity extends InjectableActivity {
    public static final long QUERY_UPDATE_DELAY_MILLIS = 200;
    public static final long QUERY_TIMEOUT = 2000;
    TextView title;
    LinearLayout navTitleLayout;
    LinearLayout titleLeft;
    LinearLayout titleRight;
    ImageView rightBtn;
    ImageView right2Btn;
    ImageView leftBtn;
    RelativeLayout leftLayout;
    FrameLayout rightLayout;
    FrameLayout right2Layout;
    ImageView rightLine;
    ImageView leftLine;
    FrameLayout actionbarRightStatus;
    EditText searchText;
    RelativeLayout searchRight;
    RelativeLayout searchBox;
    private OnSearchListener listener;
    private boolean searching = false;
    public static final int RIGHT_STATUS_INDEX = -1;
    private TextView rightTitle;
    private TextView leftTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupActionBar();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void setupActionBar() {
        title = (TextView) findViewById(R.id.actionbar_title);
        if(title == null) return;
        navTitleLayout = (LinearLayout) findViewById(R.id.inner_title_layout);
        titleLeft = (LinearLayout) findViewById(R.id.actionbar_title_left);
        leftTitle = (TextView) findViewById(R.id.title_left);
        rightTitle = (TextView) findViewById(R.id.title_right);
        titleRight = (LinearLayout) findViewById(R.id.actionbar_title_right);
        rightBtn = (ImageView) findViewById(R.id.actionbar_right);
        right2Btn = (ImageView) findViewById(R.id.actionbar_right2);
        leftBtn = (ImageView) findViewById(R.id.actionbar_left);
        leftLayout = (RelativeLayout) findViewById(R.id.actionbar_left_layout);
        rightLayout = (FrameLayout) findViewById(R.id.actionbar_right_layout);
        right2Layout = (FrameLayout) findViewById(R.id.actionbar_right2_layout);
        rightLine = (ImageView) findViewById(R.id.actionbar_title_right_line);
        leftLine = (ImageView) findViewById(R.id.actionbar_title_left_line);
        actionbarRightStatus = (FrameLayout) findViewById(R.id.actionbar_right_status);
        searchText = (EditText) findViewById(R.id.actionbar_search_text);
        searchRight = (RelativeLayout) findViewById(R.id.actionbar_search_right);
        searchBox = (RelativeLayout) findViewById(R.id.search_box_layout);
        titleRight.setTag(false);
        updateLeftBtn();
        updateTitle();
        updateRightBtn();
        updateRight2Btn();
    }

	/**
	 * trigger search ui called to show or hide search view
	 * 
	 * @param enable
	 */
    public void triggerSearchUi(boolean enable){
        searchBox.setVisibility(enable ? View.VISIBLE : View.GONE);
        searchRight.setVisibility(enable ? View.GONE : View.VISIBLE);
        leftBtn.setImageResource(enable ? R.drawable.back : getActionBarLeftResourceId());
        if(enable) {
            leftLayout.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    triggerSearchUi(false);
                    updateLeftBtn();
                }
            });
        }
        if(listener != null){
            if(enable) listener.onEnterSearchMode();
            else listener.onExitSearchMode();;
        }
        searching = enable;
    }

	/**
	 * update left button image when resource changes
	 */
    protected void updateLeftBtn(){
        leftBtn.setImageResource(getActionBarLeftResourceId());
        leftLayout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                onActionBarLeftClick();
            }
        });
    }

    protected  void updateSearch() {
        searchText.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                // TODO Auto-generated method stub
                if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) { //Whenever you got user click enter. Get text in edittext and check it equal test1. If it's true do your code in listenerevent of button3
                    if (listener != null) {
                        listener.onSearchEnter();
                        return true;
                    }
                }
                return false;
            }
        });
        RxTextView.textChangeEvents(searchText)
                .filter(new Func1<TextViewTextChangeEvent, Boolean>() {
                    @Override
                    public Boolean call(TextViewTextChangeEvent textViewTextChangeEvent) {
                        return textViewTextChangeEvent.text().length() > 0;
                    }
                })
                .debounce(QUERY_UPDATE_DELAY_MILLIS, TimeUnit.MILLISECONDS)
                .flatMap(new Func1<TextViewTextChangeEvent, Observable<String>>() {
                    @Override
                    public Observable<String> call(TextViewTextChangeEvent textViewTextChangeEvent) {
                        return Observable.just(textViewTextChangeEvent.text().toString());
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                               @Override
                               public void call(String s) {
                                   DLog.d("search:", s);
                                   if (listener != null)
                                       listener.onTextChanged(s);
                               }
                           }
                );
    }

    public void setSearchListener(OnSearchListener listener) {
        this.listener = listener;
        updateSearch();
    }

	/**
	 * whether search mode is enabled or search ui is shown.
	 */
    public boolean isSearching() {
        return searching;
    }

    public String getRightTitle() {
        return null;
    }

    public String getLeftTitle() {
        return null;
    }

    /**
	 * Search listener triggers when search <u>mode enable,</u> <u>search keyword
	 * changes</u>, and <u>exit search mode</u>. When keyword changes, the search is
	 * happend across local list  adapter's dataset, and <i>onSearchEnter()</i> is
	 * responsible for retrieve network search result when use hit enter.
	 * @author JeffreyHe
	 * @version 1.0
	 * @updated 25-一月-2016 15:39:39
	 */
    public static interface OnSearchListener{
		/**
		 * called whenever search keyword changes
		 * 
		 * @param text
		 */
        void onTextChanged(String text);
		/**
		 * called when use hit enter to retrieve network search result
		 */
        void onSearchEnter();
		/**
		 * called when trigger search mode and show the search UI.
		 */
        void onEnterSearchMode();
		/**
		 * Called when trigger exiting search mode and hide search UI.
		 */
        void onExitSearchMode();
    }

    protected void updateRightBtn() {
        if (getActionBarRightResourceId() != 0 && getActionBarRightResourceId() != RIGHT_STATUS_INDEX) {
            rightBtn.setImageResource(getActionBarRightResourceId());
            rightLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onActionBarRightClick();
                }
            });
            rightLayout.setVisibility(View.VISIBLE);
            actionbarRightStatus.setVisibility(View.GONE);
        } else {
            rightLayout.setVisibility(View.GONE);
            actionbarRightStatus.setVisibility(View.GONE);
        }
        if (getActionBarRightResourceId() == RIGHT_STATUS_INDEX) {
            rightLayout.setVisibility(View.GONE);
            actionbarRightStatus.setVisibility(View.VISIBLE);
            actionbarRightStatus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onActionBarRightStatusClick();
                }
            });
        }
    }

    protected void updateRight2Btn() {
        if (getActionBarRight2ResourceId() != 0) {
            right2Btn.setImageResource(getActionBarRight2ResourceId());
            right2Layout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onActionBarRight2Click();
                }
            });
            right2Layout.setVisibility(View.VISIBLE);
        } else {
            right2Layout.setVisibility(View.GONE);
        }
    }

    /**
     * update title when title changes
     */
    protected void updateTitle() {
        if (getActionBarTitleStringId() != 0) {
            title.setText(getActionBarTitleStringId());
            title.setVisibility(View.VISIBLE);
            navTitleLayout.setVisibility(View.GONE);
            return;
        }
        if (getActionBarTitleString() != null) {
            title.setVisibility(View.VISIBLE);
            title.setText(getActionBarTitleString());
            navTitleLayout.setVisibility(View.GONE);
            return;
        }

        if(null != getRightTitle() && null != getLeftTitle()) {
            title.setVisibility(View.GONE);
            navTitleLayout.setVisibility(View.VISIBLE);
            leftTitle.setText(getLeftTitle());
            rightTitle.setText(getRightTitle());
            showTitleLayout();
        }
    }

    private void showTitleLayout() {
        titleLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                leftLine.setVisibility(View.VISIBLE);
                rightLine.setVisibility(View.GONE);
                onTitleLeftClick();
            }
        });
        titleRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                rightLine.setVisibility(View.VISIBLE);
                leftLine.setVisibility(View.GONE);
                onTitleRightClick();
            }
        });

    }

    protected String getActionBarTitleString() {
        return null;
    }

    protected int getActionBarLeftResourceId() {
        return R.drawable.actionbar_menu;
    }

    protected int getActionBarRight2ResourceId() {
        return 0;
    }

    protected int getActionBarRightResourceId() {
        return 0;
    }

	/**
	 * actionbar left image icon click
	 */
    protected void onActionBarLeftClick() {
    }

	/**
	 * called when the second image icon from right is clicked
	 */
    protected void onActionBarRight2Click() {
    }

	/**
	 * right image icon click
	 */
    protected void onActionBarRightClick() {
    }

    protected void onActionBarRightStatusClick() {
    }

    protected int getActionBarTitleStringId() {
        return 0;
    }

    @Override
    public void onBackPressed() {
        this.finish();
        //super.onBackPressed();
        //this cause webview memory leaking around fragment, activity lifecycle
    }

	/**
	 * middle left title clicked
	 */
    protected void onTitleLeftClick() {
    }

    protected void onTitleRightClick() {
    }

    public LinearLayout getTitleRight() {
        return titleRight;
    }

}
